var gulp = require('gulp'),
    browserSync = require('browser-sync').create(),
    webpack = require('webpack'),
    webpackStream = require('webpack-stream'),
    webpackDevMiddleware = require('webpack-dev-middleware'),
    webpackHotMiddleware = require('webpack-hot-middleware'),
    stripAnsi = require('strip-ansi'),
    webpackSevConfig = require('./webpack.config.sev'),
    webpackProConfig = require('./webpack.config.pro'),
    concat = require('gulp-concat'),
    sass = require('gulp-sass'),
    gulpif = require('gulp-if'),
    htmlmin = require('gulp-htmlmin'),
    less = require('gulp-less'),
    sass = require('gulp-sass'),
    autoprefixer = require('gulp-autoprefixer'),
    minifyCss = require('gulp-minify-css'),
    base64 = require('gulp-base64'),
    uglify = require('gulp-uglify'),
    imagemin = require('gulp-imagemin'),
    pngquant = require('imagemin-pngquant'),
    rename = require('gulp-rename'),
    del = require('del'),
    newer = require('gulp-newer'),
    nodemon = require('gulp-nodemon');

var cmd = process.argv.join(',').toLowerCase(),
    IS_SEV = false, IS_DEV = false, IS_STG = false, // server|development|staging
    IS_MD = true, IS_IOS = false, // android|ios css style
    CONFIG_SEV = './app/js/config/config.sev.js',
    CONFIG_DEV = './app/js/config/config.dev.js',
    CONFIG_STG = './app/js/config/config.stg.js';

gulp.task('html', function() {
    return gulp.src('app/**/*.html')
        .pipe(newer('www/'))
        .pipe(gulpif(!IS_SEV, htmlmin({
            removeComments: true,
            collapseWhitespace: true,
            collapseBooleanAttributes: true,
            useShortDoctype: true,
            removeScriptTypeAttributes: true,
            removeStyleLinkTypeAttributes: true,
            minifyJS: true,
            minifyCSS: true
        })))
        .pipe(browserSync.reload({stream: true}))
        .pipe(gulp.dest('www/'));
});

gulp.task('script', function (done) {
    if (IS_SEV) {//use webpack-dev-server to speed up
        done();
        return;
    }
    var src = ['app/**/*.js', '!app/js/+(config)/*.js', '!app/lib/**'];
    webpackProConfig.entry.unshift(IS_DEV ? CONFIG_DEV : IS_STG ? CONFIG_STG : CONFIG_SEV);
    return gulp.src(src)
        .pipe(webpackStream(webpackProConfig))
        .pipe(gulpif(function(file){
            return file.extname === '.js';
        }, uglify()))
        .pipe(gulp.dest('www/js/'));
});

const autoprefixerConfig = {
    browsers: ['last 2 versions', 'iOS >= 7', 'Android >= 4']
};

gulp.task('sass', function () {
    var src_android = 'app/css/app.md.scss',
        src_ios = 'app/css/app.ios.scss',
        src = IS_IOS ? src_ios : src_android;
    return gulp.src(src)
        .pipe(sass({outputStyle: 'expanded', indentWidth: 4}).on('error', sass.logError))
        .pipe(autoprefixer(autoprefixerConfig))
        .pipe(gulpif(!IS_SEV, minifyCss()))
        .pipe(base64({
            baseDir: '',
            extensions: ['png', 'jpg', 'gif', 'svg'],
            exclude: [],
            maxImageSize : 10*1024, // 10KB 
            debug: false
        }))
        .pipe(rename('app.bundle.css'))
        .pipe(browserSync.reload({stream: true}))
        .pipe(gulp.dest('www/css/'));
});

gulp.task('less', function (done) {
    var style = IS_IOS ? 'ios' : 'material';
    var cbs = 0;
    ['framework7.'+style+'.less', 'framework7.'+style+'.rtl.less', 'framework7.'+style+'.colors.less'].forEach(function(lessFilePath, b){
        lessFilePath = 'app/lib/framework7/less/'+style+'/' + lessFilePath;
        gulp.src([lessFilePath])
            .pipe(less())
            .pipe(autoprefixer(autoprefixerConfig))
            .pipe(gulpif(!IS_SEV, minifyCss()))
            .pipe(rename(function(file) {
                file.basename = file.basename.replace('.'+style, '');
            }))
            .pipe(gulp.dest('www/css/'))
            .on('end', function() {
                cbs ++;
                if(cbs === 3) {
                    done();
                }
            });
    });
});

gulp.task('image', function() {
    return gulp.src('app/img/**/*.*')
        .pipe(newer('www/img/'))
        .pipe(imagemin({
            optimizationLevel: 5,
            progressive: true,
            interlaced: true,
            multipass: true,
            svgoPlugins: [{
                removeViewBox: false
            }],
            use: [pngquant()]
        }))
        .pipe(gulp.dest('www/img/'));
});

gulp.task('copy', function(done) {
    gulp.src(['app/+(fonts)/**'])
        .pipe(gulp.dest('www/'));

    var jssrc = IS_SEV ? ['app/lib/**/*.js', '!app/lib/**/*.min.js'] : ['app/lib/**/*.min.js'];
    gulp.src(jssrc)
        .pipe(gulpif(!IS_SEV, uglify()))
        .pipe(rename(function(file) {
            file.dirname = '';
            file.basename = file.basename.replace('.min', '');
        }))
        .pipe(gulp.dest('www/js'));

    done();
});

gulp.task('clean', function(done) {
    // return del(['www/**'], done);
    del.sync('www/**/*', {force: true});
    done();
});

gulp.task('envsetting', function(){
    // console.log(cmd)
    IS_DEV = cmd.includes('dev')||cmd.includes('--d');
    IS_STG = cmd.includes('stg')||cmd.includes('--s');
    IS_SEV = cmd.includes('serve');

    IS_MD = !cmd.includes('ios');
    IS_IOS = !IS_MD;

    var msg = ['==================='];
    IS_SEV && msg.push('BROSWER-DEBUG');
    IS_MD ? msg.push('MATERIAL') : IS_IOS ? msg.push('IOS') : msg.push('MATERIAL');
    IS_DEV ? msg.push('DEVELOPING') : IS_STG ? msg.push('STAGING') : msg.push('SERVING');
    msg.push('===========');
    console.log(msg.join(' '));

});

gulp.task('build', [
    'envsetting', 'clean',
    'html', 'sass', 'less', 'script',
    'image', 'copy'
], function() {
    return gulp.src(['www/css/app.bundle.css', 'www/js/app.bundle.css'])
        .pipe(concat('app.bundle.css'))
        .pipe(gulp.dest('www/css/'));
}).on('stop',function(){
    del.sync(['www/js/app.bundle.css']);
});

gulp.task('server', function() {

    webpackSevConfig.entry.unshift(IS_DEV ? CONFIG_DEV : IS_STG ? CONFIG_STG : CONFIG_SEV);
    var webpackComplier = webpack(webpackSevConfig);
    /**
     * Reload all devices when webpackComplier is complete
     * or send a fullscreen error message to the browser instead
     */
    webpackComplier.plugin('done', function (stats) {
        if (stats.hasErrors() || stats.hasWarnings()) {
            // console.log(stats.compilation.errors[0].message)
            // var msg = stripAnsi(stats.toString());
            // console.log(stats.hasErrors());
            // console.log(stats.compilation.warnings);
            var msg = stats.compilation.errors[0] && stats.compilation.errors[0].message 
                || stats.compilation.warnings[0] && stats.compilation.warnings[0].message || "";
            msg = stripAnsi(msg).replace('<', '&lt');
            return browserSync.notify('<pre style="white-space: pre-wrap;text-align: left;font-family: Consolas;color: #BEBEBE;">'+msg+'</pre>', 1000000);
        }
        browserSync.reload(); //HMR1,Refresh the page manually
    });
    browserSync.init({
        server: {
            baseDir: 'www'
        },
        browser: ["google chrome"],
        port: 3000,
        open: cmd.includes('--o'),
        notify: !cmd.includes('--n'),
        reloadOnRestart: true,
        logFileChanges: true,
        middleware: IS_SEV&&[
            webpackDevMiddleware(webpackComplier, {
                publicPath: webpackSevConfig.output.publicPath,
                stats: {colors: true},
                noInfo: true,
                quiet: false
            }),
            // webpackHotMiddleware(webpackComplier),//HMR2, You can disable hot replacement when appear bugs, and refresh the page manually
            // function(req, res, next) {
            //     require('./api/main')(req, res, next);
            // }
        ]
    });

    gulp.watch('app/**/*.html', ['html']);
    // gulp.watch('app/**/*.js', ['script']);
    gulp.watch('app/**/*.scss', ['sass']);
    gulp.watch('app/lib/framework7/less/*/*.less', ['less']);
    gulp.watch('app/img/*.*', ['image']);
    gulp.watch('app/+(fonts|svg|lib)/**', ['copy']);

    // browserSync.watch('www/**').on('change', browserSync.reload);
});

gulp.task('hotexpress', function() {
    var node_env = IS_DEV ? 'dev' : IS_STG ? 'stg' : 'sev';
    return nodemon({
        restartable: 'rs',
        script: 'api/app.js',
        watch: ['api'],
        ext: 'js json',
        execMap: { js: 'node' },
        env: { 'NODE_ENV': node_env }
    }).on('start', function() {
        browserSync.reload();
    });
});

var handlebars = require('gulp-handlebars');
var wrap = require('gulp-wrap');
var declare = require('gulp-declare');
 
gulp.task('templates', function(){
  gulp.src('app/**/*.hbs')
    .pipe(handlebars())
    .pipe(wrap('Handlebars.template(<%= contents %>)'))
    .pipe(declare({
      namespace: 'MyApp.templates',
      noRedeclare: true, // Avoid duplicate declarations 
    }))
    .pipe(concat('templates.js'))
    .pipe(gulp.dest('build/js/'));
});

gulp.task('serve', ['build'], function(){
    gulp.start('server');
    if (cmd.includes('--e')) {
        gulp.start('hotexpress');
    }
});
gulp.task('serve:ios', ['build'], function(){
    gulp.start('server');
    if (!IS_DEV && !IS_STG) {
        gulp.start('hotnode');
    }
});

gulp.task('build:dev', ['build']);
gulp.task('build:dev:ios', ['build']);

gulp.task('build:stg', ['build']);
gulp.task('build:stg:ios', ['build']);

